#include "Acceptor.h"

/*---调试用 ---*/
//#include<iostream>
//using std::cout;
//using std::endl;
/*
Acceptor::Acceptor(epollEngine& ep, doubleBufferedQueue<epoll_event>& q, int s):
IOMultiplexer(ep), IOQueue(q), serverSocket(s), status(0)
{

}*/


void Acceptor::AcceptorCycle()
{
    int size = 0;
    Socket conn_sock;
    int accept_sock = -1;
    epoll_event temp;
    connection_t* acceptConn;
    auto logger = utils.logger.setBasicLogger("acceptor");
    if(utils.serverSocket < 0){
        //log: invalid serverSocket
        this->status = -1;
        return;
    }
    connection_t* serverConn = utils.connections.getFreeConnection();
    serverConn->setConnnection(utils.serverSocket, LOCAL_CONNECTION, nullptr, nullptr, false);
    temp = utils.IOMultiplexer.setEpollEvent(utils.serverSocket, EPOLLIN | EPOLLET, (void*)serverConn);
    if(!utils.IOMultiplexer.epollAddEvent(temp, utils.serverSocket)) //将监听socket添加入epoll中，监听socket设为ET
    {
        logger->critical("添加监听socket失败，原因是：{}", MyLogger::getSysError().c_str());   
        perror("添加监听socket失败");
        return;
    }
    //main cycle
    while(status >= 0)
    {
    	size = utils.IOMultiplexer.epollWait();
        if(size == 0){
	    //cout << "empty set" << endl;
	    }
        else if(size < 0){
            this-> status = -1;
            //cout << "epollWait failed!"<<endl;
            break;
        }
        else{
            //std::cout << "from acceptor: 接收到"<< size <<"个新连接" << std::endl;
            vector<epoll_event>& events = utils.IOMultiplexer.getEventList(); 
            bool flag = utils.queue.Empty();
            utils.queue.Push(events, size); //将就绪fd插入队列
            if(flag == true){
                utils.conn.notify_all();
            }
            for(int i = 0; i < size; ++i){
                acceptConn = (connection_t*) events[i].data.ptr;
                if(acceptConn->fd == utils.serverSocket){
                    conn_sock.changeSocket(utils.serverSocket, SERVER_SOCKET);
                    while((accept_sock=conn_sock.Accept()) > 0){ 
                        //epoll et mode
                        //从连接池获取空闲连接结构体
                        connection_t* newConn = utils.connections.getFreeConnection();
                        newConn->setConnnection(accept_sock, LOCAL_CONNECTION, nullptr, nullptr, false); //设为用户连接
                        newConn->addr = conn_sock.getAddr();
                        newConn->addrlen = conn_sock.getAddrLen();
                        newConn->ev = EPOLLIN | EPOLLET;
                        Socket::setNonblockingSocket(accept_sock);
                        temp = utils.IOMultiplexer.setEpollEvent(accept_sock, EPOLLIN | EPOLLET, (void*)newConn);
                        utils.IOMultiplexer.epollAddEvent(temp, accept_sock);
			            //cout << "add socket "<<accept_sock<< " to epoll" << endl;
                    }
		             //cout << "done with handling all of the sockets" << endl;
                    if (errno != EAGAIN){
                        this->status = -1;
                        //perror("accept error");
                    }
                    break;
                }
            }
        }
    }
    //cout<< "Acceptor main thread exited!"<<endl;
}

void Acceptor::run()
{
    status = 0;
    std::thread AcceptorThread(&Acceptor::AcceptorCycle, this);
    AcceptorThread.detach();
}
